#include "firmware_update.h"
#include "error_code.h"
#include <string.h>


// Flash地址定义
#define APP2_START_ADDR    0x800F000
#define APP2_END_ADDR      0x801E000
#define APP2_SIZE          (APP2_END_ADDR - APP2_START_ADDR)

// 错误码定义
#define BOOT_ERR_NONE      0x00
#define BOOT_ERR_ADDR      0x01
#define BOOT_ERR_FLASH     0x02
#define BOOT_ERR_CRC       0x03
#define BOOT_ERR_SIZE      0x04


#define BOOT_BLOCK_SIZE    1024    // 1KB per block
#define APP2_TOTAL_BLOCKS  60      // 60KB total size


// modbus_tcp.c
 boot_status_t boot_status = {
    .state = BOOT_STATE_IDLE,
    .current_block = 0,
    .crc = 0
};


// 写入启动参数
HAL_StatusTypeDef write_boot_param(BootParam_t *param)
{
    // 擦除参数区
    if(Flash_Erase_Pages(BOOT_PARAM_ADDR, BOOT_PARAM_ADDR + sizeof(BootParam_t)) != HAL_OK) {
        return HAL_ERROR;
    }
    
    // 写入参数
    return Flash_Write_Data(BOOT_PARAM_ADDR, (uint8_t*)param, sizeof(BootParam_t));
}

// 读取启动参数
HAL_StatusTypeDef read_boot_param(BootParam_t *param)
{
    // 直接从Flash读取
    memcpy(param, (void*)BOOT_PARAM_ADDR, sizeof(BootParam_t));
    
    // 验证魔数
    if(param->magic != BOOT_MAGIC) {
        return HAL_ERROR;
    }
    
    return HAL_OK;
}

// 清除启动参数
HAL_StatusTypeDef clear_boot_param(void)
{
    return Flash_Erase_Pages(BOOT_PARAM_ADDR, BOOT_PARAM_ADDR + sizeof(BootParam_t));
}

// 通过检查中断向量表位置判断当前运行在哪里
RunningApp_t get_running_app(void) {
    uint32_t vector_addr = SCB->VTOR;
    if(vector_addr == APP2_START_ADDR) {
        return RUNNING_APP2;
    }
    return RUNNING_APP1;
}

void firmware_update_init(void)
{
    boot_status.state = BOOT_STATE_IDLE;
    boot_status.current_block = 0;
    boot_status.crc = 0;
}


uint8_t handle_boot_verify(uint32_t crc)
{
    // 验证CRC
    if(boot_status.crc != crc) {
        return BOOT_ERR_CRC;
    }
    return BOOT_ERR_NONE;
}

uint8_t handle_boot_activate(void)
{
    // 设置激活标志
    boot_status.state = BOOT_STATE_DONE;
    return BOOT_ERR_NONE;
}




// 修改boot写入处理函数
// 使用param_storage.c的函数，新增boot相关处理
uint8_t handle_boot_write(uint8_t block_num, uint8_t *data)
{
    if(block_num >= APP2_TOTAL_BLOCKS) {
        return BOOT_ERR_ADDR;
    }
    

    uint32_t target_addr;

    // 计算实际写入地址
    target_addr += (block_num * BOOT_BLOCK_SIZE);
    


    
    // 写入固件
    if(Flash_Erase_Pages(target_addr, target_addr + BOOT_BLOCK_SIZE - 1) != HAL_OK) {
        return BOOT_ERR_FLASH;
    }
    
    if(Flash_Write_Data(target_addr, data, BOOT_BLOCK_SIZE) != HAL_OK) {
        return BOOT_ERR_FLASH;
    }
    
    boot_status.current_block = block_num;
    boot_status.crc = Calc_CRC32(data, BOOT_BLOCK_SIZE);
    
    return BOOT_ERR_NONE;
    
}